﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq.Expressions;
using FikriKibar.Common.Helpers;
using FikriKibar.DataAccess.Abstract;
using FikriKibar.Entities.Abstract;

namespace FikriKibar.DataAccess.RepositoryBase
{
    public abstract class EfEntityRepositoryBase<TEntity, TContext> : IEntityRepository<TEntity> where TEntity : class, IEntity, new() where TContext : DbContext, new()
    {
        protected abstract TEntity AddEntity(TEntity entity, TContext context);
        protected abstract TEntity UpdateEntity(TEntity entity, TContext context);
        protected abstract List<TEntity> GetEntities(TContext context);
        protected abstract List<TEntity> FilterEntities(TContext context, Expression<Func<TEntity, bool>> where);
        protected abstract List<TEntity> FilterEntities(TContext context, Expression<Func<TEntity, bool>> where, SortHelper<TEntity> sortHelper);
        protected abstract List<TEntity> FilterEntities(TContext context, Expression<Func<TEntity, bool>> where, SortHelper<TEntity> sortHelper, int index, int size);
        protected abstract TEntity GetEntity(TEntity entity, TContext context);

        public List<TEntity> GetAll()
        {
            using (var context = new TContext())
            {
                return GetEntities(context);
            }
        }

        public TEntity Add(TEntity entity)
        {
            using (var context = new TContext())
            {
                var addedEntity = AddEntity(entity, context);
                context.SaveChanges();
                return addedEntity;
            }
        }

        public TEntity Get(TEntity entity)
        {
            using (var context = new TContext())
            {
                return GetEntity(entity, context);
            }
        }

        public TEntity Update(TEntity entity)
        {
            using (var context = new TContext())
            {
                var updatedEntity = UpdateEntity(entity, context);
                context.SaveChanges();
                return updatedEntity;
            }
        }

        public void Delete(TEntity entity)
        {
            using (var context = new TContext())
            {
                context.Entry(entity).State = EntityState.Deleted;
                context.SaveChanges();
            }
        }

        public List<TEntity> Filter(Expression<Func<TEntity, bool>> where)
        {
            using (var context = new TContext())
            {
                return FilterEntities(context, where);
            }
        }

        public List<TEntity> Filter(Expression<Func<TEntity, bool>> where, SortHelper<TEntity> sortHelper)
        {
            using (var context = new TContext())
            {
                return FilterEntities(context, where,sortHelper);
            }
        }

        public List<TEntity> Filter(Expression<Func<TEntity, bool>> where, SortHelper<TEntity> sortHelper, int index, int size)
        {
            using (var context = new TContext())
            {
                return FilterEntities(context, where, sortHelper, index, size);
            }
        }
    }
}
